from pyjvm.instructions.common import Instruction, BytecodeReader
from pyjvm.runtime.thread import Frame


class POP(Instruction):
    """
    弹出栈顶元素
    """

    def execute(self, frame: Frame):
        frame.operand_stack.pop()


class POP2(Instruction):
    """
    弹出两次栈顶元素
    """

    def execute(self, frame: Frame):
        stack = frame.operand_stack
        stack.pop()
        # stack.pop()
        # 使用python，操作数栈long，double类型只弹出一次栈就行了
        # pyjvm.rumtime.rumtime_data_area OperandStack


class DUP(Instruction):
    """
    复制栈顶元素
    """

    def execute(self, frame: Frame):
        stack = frame.operand_stack
        stack.push(stack[-1])


class DUP2(DUP):
    """
    复制栈顶元素
    """
    pass

    # def execute(self, frame: Frame):
    #     stack = frame.operand_stack
    #     top2 = stack[-2]
    #     top1 = stack[-1]
    #     stack.push(top2)
    #     stack.push(top1)


class DUP_X1(Instruction):
    """
    复制栈顶元素，并将弹出的两字压栈
    相当于，将栈顶元素复制一份，插入到倒数第三个位置
    """

    def execute(self, frame: Frame):
        stack = frame.operand_stack
        stack.insert(-2, stack[-1])


class DUP2_X1(DUP_X1):
    """
    复制栈顶两个元素，并将弹出的两字压栈
    相当于，将栈顶两个元素复制一份，插入到倒数第4个位置
    """
    pass

    # def execute(self, frame: Frame):
    #     stack = frame.operand_stack
    #     top2 = stack[-2]
    #     top1 = stack[-1]
    #     stack.insert(-3, top2)
    #     stack.insert(-3, top1)


class DUP_X2(Instruction):
    """
    复制栈顶元素，并将弹出的三元素压栈
    相当于，将栈顶元素复制一份，插入到倒数第4个位置
    """

    def execute(self, frame: Frame):
        stack = frame.operand_stack
        stack.insert(-3, stack[-1])


class DUP2_X2(Instruction):
    """
    复制栈顶两个元素，并将弹出的三元素压栈
    相当于，将栈顶两个元素复制一份，插入到倒数第5个位置
    """
    pass
    #
    # def execute(self, frame: Frame):
    #     stack = frame.operand_stack
    #     top2 = stack[-2]
    #     top1 = stack[-1]
    #     stack.insert(-4, top2)
    #     stack.insert(-4, top1)


class SWAP(Instruction):
    """
    交换栈顶两个元素
    """

    def execute(self, frame: Frame):
        stack = frame.operand_stack
        stack.push(stack.pop(-2))


__all__ = ['POP', 'POP2', 'DUP', 'DUP_X1', 'DUP_X2', 'DUP2', 'DUP2_X1', 'DUP2_X2', 'SWAP']
